package co.edu.usbcali.sap.presentation.backEndBeans;

import co.edu.usbcali.sap.exceptions.*;
import co.edu.usbcali.sap.modelo.*;
import co.edu.usbcali.sap.modelo.dto.ComiteDTO;
import co.edu.usbcali.sap.modelo.dto.PersonaDTO;
import co.edu.usbcali.sap.modelo.dto.ProyectoDTO;
import co.edu.usbcali.sap.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.sap.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.component.selectinputtext.SelectInputText;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;

/**
 * 
 * 
 * @author Zathura Code Generator http://code.google.com/p/zathura
 * 
 */
public class ComiteView extends DataSource implements Renderable,
		DisposableBean {
	private HtmlInputText txtComCodigo;
	private SelectInputText txtIntegrantes;
	private HtmlInputText txtPerNombre;
	private HtmlInputText txtPerCodigo;
	private SelectInputDate txtComFechacreacion;
	private SelectInputDate txtComFechafinalizacion;
	private HtmlCommandButton btnAdd;
	private HtmlCommandButton btnRemove;
	private HtmlCommandButton btnAdd2;
	private HtmlCommandButton btnRemove2;
	private HtmlCommandButton btnSave;
	private HtmlCommandButton btnModify;
	private HtmlCommandButton btnDelete;
	private HtmlCommandButton btnClear;
	private boolean renderDataTable;
	private boolean flag = true;
	private RenderManager renderManager;
	private PersistentFacesState state = PersistentFacesState.getInstance();

	private List<Persona> persona = new ArrayList<Persona>();
	private List<Persona> model = new ArrayList<Persona>();
	private List<PersonaDTO> model2 = new ArrayList<PersonaDTO>();
	private List<SelectItem> item = new ArrayList<SelectItem>();

	private List<Comite> comite = new ArrayList<Comite>();
	private List<ComiteDTO> comiteDTO = new ArrayList<ComiteDTO>();

	// private List<Comite> comite;
	// private List<ComiteDTO> comiteDTO;

	public ComiteView() {
		super("");
	}

	public SelectInputText getTxtIntegrantes() {
		return txtIntegrantes;
	}

	public void setTxtIntegrantes(SelectInputText txtIntegrantes) {
		this.txtIntegrantes = txtIntegrantes;
	}

	public HtmlInputText getTxtPerNombre() {
		return txtPerNombre;
	}

	public void setTxtPerNombre(HtmlInputText txtPerNombre) {
		this.txtPerNombre = txtPerNombre;
	}

	public HtmlInputText getTxtPerCodigo() {
		return txtPerCodigo;
	}

	public void setTxtPerCodigo(HtmlInputText txtPerCodigo) {
		this.txtPerCodigo = txtPerCodigo;
	}

	public HtmlCommandButton getBtnAdd() {
		return btnAdd;
	}

	public void setBtnAdd(HtmlCommandButton btnAdd) {
		this.btnAdd = btnAdd;
	}

	public HtmlCommandButton getBtnRemove() {
		return btnRemove;
	}

	public void setBtnRemove(HtmlCommandButton btnRemove) {
		this.btnRemove = btnRemove;
	}

	public HtmlCommandButton getBtnAdd2() {
		return btnAdd2;
	}

	public void setBtnAdd2(HtmlCommandButton btnAdd2) {
		this.btnAdd2 = btnAdd2;
	}

	public HtmlCommandButton getBtnRemove2() {
		return btnRemove2;
	}

	public void setBtnRemove2(HtmlCommandButton btnRemove2) {
		this.btnRemove2 = btnRemove2;
	}

	public List<Persona> getPersona() {
		return persona;
	}

	public void setPersona(List<Persona> persona) {
		this.persona = persona;
	}

	public List<Persona> getModel() {
		return model;
	}

	public void setModel(List<Persona> model) {
		this.model = model;
	}

	public List<PersonaDTO> getModel2() {
		return model2;
	}

	public void setModel2(List<PersonaDTO> model2) {
		this.model2 = model2;
	}

	public List<SelectItem> getItem() {
		return item;
	}

	public void setItem(List<SelectItem> item) {
		this.item = item;
	}

	public String action_clear() {
		txtComFechacreacion.setValue(null);
		txtComFechacreacion.setDisabled(true);
		txtComFechafinalizacion.setValue(null);
		txtComFechafinalizacion.setDisabled(true);
		txtComCodigo.setValue(null);
		txtComCodigo.setDisabled(false);
		btnSave.setDisabled(true);
		btnDelete.setDisabled(true);
		btnModify.setDisabled(true);
		btnClear.setDisabled(false);
		model2.clear();
		txtIntegrantes.setDisabled(true);
		btnAdd2.setDisabled(true);

		return "";
	}

	public String action_retirar(Integer perCodigo, String perNombre)
			throws Exception {
		int x = 0;
		for (PersonaDTO persona3 : model2) {
			if (persona3.getPerCodigo().equals(perCodigo + "")) {
				model2.remove(x);
				break;
			}
			x++;
		}

		return "";
	}

	public void listener_txtId(ValueChangeEvent event) {
		if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
			Comite entity = null;

			try {
				Integer comCodigo = new Integer(txtComCodigo.getValue()
						.toString());
				entity = BusinessDelegatorView.getComite(comCodigo);

				if (entity == null) {
					txtComFechacreacion.setDisabled(false);
					txtComFechafinalizacion.setDisabled(false);
					txtComCodigo.setDisabled(false);
					btnSave.setDisabled(false);
					btnDelete.setDisabled(true);
					btnModify.setDisabled(true);
					btnClear.setDisabled(false);
					txtIntegrantes.setDisabled(false);
					btnAdd2.setDisabled(false);
				} else {
					txtComFechacreacion.setValue(entity.getComFechacreacion());
					txtComFechacreacion.setDisabled(false);
					txtComFechafinalizacion.setValue(entity
							.getComFechafinalizacion());

					txtComFechafinalizacion.setDisabled(false);
					txtComCodigo.setValue(entity.getComCodigo());
					txtComCodigo.setDisabled(true);
					btnSave.setDisabled(true);
					btnDelete.setDisabled(false);
					btnModify.setDisabled(false);
					btnClear.setDisabled(false);
					txtIntegrantes.setDisabled(false);
					btnAdd2.setDisabled(false);
					List<Persona> list = BusinessDelegatorView
							.getPersonasFromComite(entity.getComCodigo());
					if (list != null) {
						for (Persona persona : list) {
							PersonaDTO persona2 = new PersonaDTO();
							persona2.setPerCodigo(persona.getPerCodigo() + "");
							persona2.setPerNombre(persona.getPerNombre());
							persona2.setPersona(persona);
							persona2.setComiteView(this);

							model2.add(persona2);
						}
					}
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}

	public String action_save() {
		try {
			
			String codigoper = txtPerCodigo.getValue().toString();
			String codigocom= txtComCodigo.getValue().toString();
			String nombreper = txtPerNombre.getValue().toString();
			//String integrantes = txtIntegrantes.getValue().toString();
			String fechacreacion = txtComFechacreacion.getValue().toString();
			String fechafinal = "";
		
			

			
			if(codigoper.equals("")){
				throw new Exception("El c&#243;digo de la persona  es de caracter obligatorio");
			}
			
			if(Utilities.soloNumeros(codigoper)==false){
				throw new Exception("El c&#243;digo de la persona no acepta letras ni caracteres especiales como @#$%^&*()");
			}
			
			if(codigocom.equals("")){
				throw new Exception("El c&#243;digo del comit&#233; es de caracter obligatorio");
			}
			
			if(Utilities.soloNumeros(codigocom)==false){
				throw new Exception("El c&#243;digo del comit&#233; no acepta letras ni caracteres especiales como @#$%^&*()");
			}
			
								
			if(nombreper.equals("")){
				throw new Exception("el nombre de la persona es de caracter obligatorio");
			}
			
			if(Utilities.soloLetras(nombreper)==false){
				throw new Exception("El nombre de la persona no permite n&#250;meros ni caracteres especiales como @#$%^&*()");
			}
			

			if(fechacreacion.equals("")){
				throw new Exception("La fecha de creacion es de caracter obligatorio");
			}
			
			FacesUtils.checkDate(txtComFechacreacion);
			
			if(!Utilities.compararFechas((Date)txtComFechacreacion.getValue(),(Date)txtComFechafinalizacion.getValue())){
				throw new Exception("La fecha de creaci&#243; debe ser menor que la fecha de finalizaci&#243;n");
			}
			if (model2.size()==0){
				throw new Exception("Se debe ingresar al menos un integrante");
			}

			try{
				fechafinal=txtComFechafinalizacion.getValue().toString();
			}catch (Exception e){
				
			}
			
			if (!fechafinal.equals("")){
				Date fechafini=FacesUtils.checkDate(txtComFechafinalizacion);
				
				if(!Utilities.compararFechaActualMenor(fechafini)){
					throw new Exception("La fecha de finalizaci&#243; debe ser mayor que la fecha de creaci&#243;n");
				}
				
				
			}
			
			
			
			
			BusinessDelegatorView.saveComite(new Integer(0), (Date) txtComFechacreacion.getValue(),(Date) txtComFechafinalizacion.getValue(),model2);
			FacesContext.getCurrentInstance().addMessage("", new FacesMessage("Se creo el comit&#233; con &#233;xito"));
			
		
			
			
			
			action_clear();
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage("", new FacesMessage(e.getMessage()));
		}

		return "";
			
			
	}

	public String action_modify() {
		try {
			BusinessDelegatorView.updateComite(FacesUtils
					.checkInteger(txtComCodigo), FacesUtils
					.checkDate(txtComFechacreacion), FacesUtils
					.checkDate(txtComFechafinalizacion),model2);
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modifyWitDTO(Integer comCodigo, Date comFechacreacion,
			Date comFechafinalizacion) throws Exception {
		try {
			BusinessDelegatorView.updateComite(comCodigo, comFechacreacion,
					comFechafinalizacion);
			renderManager.getOnDemandRenderer("ComiteView").requestRender();
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("ComiteView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}

		return "";
	}

	public String action_agregar2() throws Exception {
		try {
			if (model2.size() < 4) {
				String perso[] = txtIntegrantes.getValue().toString()
						.split("-");
				if (perso.length > 1 && Utilities.isNumeric((perso[1].trim()))) {
					for (PersonaDTO dto : model2) {
						if (dto.getPerCodigo().equals(perso[1].trim())) {
							FacesUtils
									.addErrorMessage("El estudiante ya ha sido ingresado");
							return "";
						}
					}

					Persona persona = BusinessDelegatorView.getPersona(Integer
							.parseInt(perso[1]));
					if (persona != null) {
						PersonaDTO persona2 = new PersonaDTO();
						persona2.setPerCodigo(persona.getPerCodigo() + "");
						persona2.setPerNombre(persona.getPerNombre());
						persona2.setPersona(persona);
						persona2.setComiteView(this);

						model2.add(persona2);
						txtIntegrantes.setValue("");
					} else {
						FacesUtils
								.addErrorMessage("El estudiante seleccionado no existe, intente seleccionar de nuevo");
					}

				} else {
					FacesUtils
							.addErrorMessage("Seleccione de manera correcta al integrante");
				}
			} else {
				FacesUtils
						.addErrorMessage("El ingreso m&#225;ximo de estudiantes es de 3");
			}

		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("ProyectoView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}
		return "";
	}

	public List<Comite> getComite() {
		if (flag) {
			try {
				comite = BusinessDelegatorView.getComite();
				flag = false;
			} catch (Exception e) {
				flag = true;
				FacesUtils.addErrorMessage(e.getMessage());
			}
		}

		return comite;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setComite(List<Comite> comite) {
		this.comite = comite;
	}

	public boolean isRenderDataTable() {
		try {
			if (flag) {
				if (BusinessDelegatorView.findTotalNumberComite() > 0) {
					renderDataTable = true;
				} else {
					renderDataTable = false;
				}
			}

			flag = false;
		} catch (Exception e) {
			renderDataTable = false;
			e.printStackTrace();
		}

		return renderDataTable;
	}

	public DataModel getData() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModel(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<Comite> getDataPage(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberComite = 0;

		try {
			totalNumberComite = BusinessDelegatorView.findTotalNumberComite()
					.intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberComite) {
			endIndex = totalNumberComite;
		}

		try {
			comite = BusinessDelegatorView.findPageComite(sortColumnName,
					sortAscending, startRow, endIndex - startRow);

			// Remove this Renderable from the existing render groups.
			// leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		// joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<Comite>(totalNumberComite, startRow, comite);
	}

	public DataModel getDataDTO() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModelDTO(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<ComiteDTO> getDataPageDTO(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberComite = 0;

		try {
			totalNumberComite = BusinessDelegatorView.findTotalNumberComite()
					.intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberComite) {
			endIndex = totalNumberComite;
		}

		try {
			comite = BusinessDelegatorView.findPageComite(sortColumnName,
					sortAscending, startRow, endIndex - startRow);

			if (Utilities.validationsList(comite)) {
				comiteDTO = new ArrayList<ComiteDTO>();

				for (Comite comiteTmp : comite) {
					ComiteDTO comiteDTO2 = new ComiteDTO();
					comiteDTO2
							.setComCodigo(comiteTmp.getComCodigo().toString());
					comiteDTO2.setComFechacreacion(comiteTmp
							.getComFechacreacion());
					comiteDTO2.setComFechafinalizacion(comiteTmp
							.getComFechafinalizacion());
					comiteDTO2.setComite(comiteTmp);
					comiteDTO2.setComiteView(this);
					comiteDTO.add(comiteDTO2);
				}
			}

			// Remove this Renderable from the existing render groups.
			leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<ComiteDTO>(totalNumberComite, startRow, comiteDTO);
	}

	protected boolean isDefaultAscending(String sortColumn) {
		return true;
	}

	/**
	 * This method is called when a render call is made from the server. Render
	 * calls are only made to views containing an updated record. The data is
	 * marked as dirty to trigger a fetch of the updated record from the
	 * database before rendering takes place.
	 */
	public PersistentFacesState getState() {
		onePageDataModel.setDirtyData();

		return state;
	}

	/**
	 * This method is called from faces-config.xml with each new session.
	 */
	public void setRenderManager(RenderManager renderManager) {
		this.renderManager = renderManager;
	}

	public void renderingException(RenderingException arg0) {
		if (arg0 instanceof TransientRenderingException) {
		} else if (arg0 instanceof FatalRenderingException) {
			// Remove from existing Customer render groups.
			leaveRenderGroups();
		}
	}

	/**
	 * Remove this Renderable from existing uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void leaveRenderGroups() {
		if (Utilities.validationsList(comiteDTO)) {
			for (ComiteDTO comiteTmp : comiteDTO) {
				renderManager.getOnDemandRenderer("ComiteView").remove(this);
			}
		}
	}

	/**
	 * Add this Renderable to the new uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void joinRenderGroups() {
		if (Utilities.validationsList(comiteDTO)) {
			for (ComiteDTO comiteTmp : comiteDTO) {
				renderManager.getOnDemandRenderer("ComiteView").add(this);
			}
		}
	}

	public void dispose() throws Exception {
	}

	public RenderManager getRenderManager() {
		return renderManager;
	}

	public void setState(PersistentFacesState state) {
		this.state = state;
	}

	public SelectInputDate getTxtComFechacreacion() {
		return txtComFechacreacion;
	}

	public void setTxtComFechacreacion(SelectInputDate txtComFechacreacion) {
		this.txtComFechacreacion = txtComFechacreacion;
	}

	public SelectInputDate getTxtComFechafinalizacion() {
		return txtComFechafinalizacion;
	}

	public void setTxtComFechafinalizacion(
			SelectInputDate txtComFechafinalizacion) {
		this.txtComFechafinalizacion = txtComFechafinalizacion;
	}

	public HtmlInputText getTxtComCodigo() {
		return txtComCodigo;
	}

	public void setTxtComCodigo(HtmlInputText txtComCodigo) {
		this.txtComCodigo = txtComCodigo;
	}

	public HtmlCommandButton getBtnSave() {
		return btnSave;
	}

	public void setBtnSave(HtmlCommandButton btnSave) {
		this.btnSave = btnSave;
	}

	public HtmlCommandButton getBtnModify() {
		return btnModify;
	}

	public void setBtnModify(HtmlCommandButton btnModify) {
		this.btnModify = btnModify;
	}

	public HtmlCommandButton getBtnDelete() {
		return btnDelete;
	}

	public void setBtnDelete(HtmlCommandButton btnDelete) {
		this.btnDelete = btnDelete;
	}

	public HtmlCommandButton getBtnClear() {
		return btnClear;
	}

	public void setBtnClear(HtmlCommandButton btnClear) {
		this.btnClear = btnClear;
	}

	public void setRenderDataTable(boolean renderDataTable) {
		this.renderDataTable = renderDataTable;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public List<ComiteDTO> getComiteDTO() {
		return comiteDTO;
	}

	public void setComiteDTO(List<ComiteDTO> comiteDTO) {
		this.comiteDTO = comiteDTO;
	}

	public TimeZone getTimeZone() {
		return java.util.TimeZone.getDefault();
	}

	/**
	 * A special type of JSF DataModel to allow a datatable and datapaginator to
	 * page through a large set of data without having to hold the entire set of
	 * data in memory at once. Any time a managed bean wants to avoid holding an
	 * entire dataset, the managed bean declares this inner class which extends
	 * PagedListDataModel and implements the fetchData method. fetchData is
	 * called as needed when the table requires data that isn't available in the
	 * current data page held by this object. This requires the managed bean
	 * (and in general the business method that the managed bean uses) to
	 * provide the data wrapped in a DataPage object that provides info on the
	 * full size of the dataset.
	 */
	private class LocalDataModel extends PagedListDataModel {
		public LocalDataModel(int pageSize) {
			super(pageSize);
		}

		public DataPage<Comite> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPage(startRow, pageSize);
		}
	}

	private class LocalDataModelDTO extends PagedListDataModel {
		public LocalDataModelDTO(int pageSize) {
			super(pageSize);
		}

		public DataPage<ComiteDTO> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPageDTO(startRow, pageSize);
		}
	}

	public void updateList(ValueChangeEvent event) throws Exception {
		try {

			String strign = event.getNewValue().toString();
			persona = BusinessDelegatorView.FindByPath(strign, "Directores");
			if (persona != null) {
				item.clear();
				for (Persona personas : persona) {
					SelectItem item2 = new SelectItem(personas, personas
							.getPerNombre()
							+ "-" + personas.getPerCodigo());
					item.add(item2);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	public String action_agregar() throws Exception {
		try {
			if (model.size() < 3) {
				String perso[] = txtIntegrantes.getValue().toString()
						.split("-");
				if (perso.length > 1 && Utilities.isNumeric((perso[1]))) {
					Persona persona = BusinessDelegatorView.getPersona(Integer
							.parseInt(perso[1]));
					if (persona != null) {
						model.add(persona);
					} else {
						FacesUtils
								.addErrorMessage("El estudiante seleccionado no existe, intente seleccionar de nuevo");
					}
				} else {
					FacesUtils
							.addErrorMessage("Seleccione de manera correcta al integrante");
				}
			} else {
				FacesUtils
						.addErrorMessage("El ingreso m&#225;ximo de estudiantes es de 3");
			}

		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("ProyectoView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}
		return "";
	}

}
